home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.1 / Graphics / scale_rastport.c < prev   
Encoding:
C/C++ Source or Header  |  1992-08-27  |  8.4 KB  |  348 lines

  1. /******************************************************************************
  2. *
  3. *   Source Control
  4. *   --------------
  5. *   $Header: algorithm.c,v 35.11 88/04/22 15:17:07 bart Exp $
  6. *
  7. *   by Bart Whitebook
  8. *
  9. * Copyright (c) 1988 Commodore-Amiga, Inc.
  10. *
  11. * Executables based on this information may be used in software
  12. * for Commodore Amiga computers.  All other rights reserved.
  13. *
  14. * This information is provided "as is"; no warranties are made.
  15. * All use is at your own risk, and no liability or responsibility is assumed.
  16. *
  17. ******************************************************************************/
  18.  
  19.  
  20. #include <exec/types.h>
  21. #include <exec/memory.h>
  22. #include <graphics/gfx.h>
  23. #include <graphics/rastport.h>
  24.  
  25. /* scale_rastport.c -- scale a portion of one rastport to fit into another */
  26.  
  27. dispose_temprp(temprp)
  28. struct RastPort *temprp;
  29. {
  30.     if(temprp)
  31.     {
  32.         struct BitMap *tempbm = temprp->BitMap;
  33.  
  34.         if(tempbm)
  35.         {
  36.             int numbytes = (tempbm->Depth * tempbm->BytesPerRow);
  37.  
  38.             if((numbytes)&&(tempbm->Planes[0]))
  39.             {
  40.                 FreeMem(tempbm->Planes[0],numbytes);    
  41.             }
  42.             FreeMem(tempbm,sizeof(*tempbm));    
  43.         }
  44.         FreeMem(temprp,sizeof(*temprp));    
  45.     }
  46. }
  47.  
  48. struct RastPort *get_temprp(srcrp)
  49. struct RastPort *srcrp;
  50. {
  51.     struct RastPort *temprp = NULL;
  52.  
  53.     if(srcrp)
  54.     {
  55.         /* allocate temprp */
  56.  
  57.         if ((temprp = (struct RastPort *)
  58.         AllocMem(sizeof(*temprp),MEMF_PUBLIC)) != NULL)
  59.         {
  60.             struct BitMap *tempbm;
  61.             UBYTE   *mem;
  62.  
  63.             /* copy srcrp */
  64.  
  65.             *temprp = *srcrp;
  66.  
  67.             /* null layer pointer */
  68.  
  69.             temprp->Layer = NULL;
  70.  
  71.             /* allocate tempbm */
  72.  
  73.             if ((tempbm = (struct BitMap *)
  74.                 AllocMem(sizeof(*tempbm),MEMF_PUBLIC)) == NULL)
  75.             {
  76.                 FreeMem(temprp,sizeof(*temprp));
  77.                 temprp = NULL;
  78.             }
  79.             else
  80.             {
  81.                 int width;
  82.                 int bytesperrow;
  83.                 int numbytes;
  84.  
  85.                 /* copy srcrp bitmap */ 
  86.  
  87.                 *tempbm = *(srcrp->BitMap);
  88.  
  89.                 /* force copy of bitmap to one line high */
  90.  
  91.                 tempbm->Rows = 1;
  92.  
  93.                 /* allocate temp memory for one line high bitmap */
  94.  
  95.                 width = srcrp->BitMap->BytesPerRow << 3;
  96.  
  97.                 if(width < 1)
  98.                 {
  99.                     FreeMem(tempbm,sizeof(*tempbm));
  100.                     FreeMem(temprp,sizeof(*temprp));
  101.                     temprp = NULL;
  102.                 }
  103.                 else
  104.                 {
  105.                     bytesperrow = (((width+0xf)>>4)<<1);
  106.  
  107.                     tempbm->BytesPerRow = bytesperrow;
  108.  
  109.                     numbytes = (tempbm->Depth * bytesperrow); 
  110.  
  111.                     if ((mem = (UBYTE *)
  112.                         AllocMem(numbytes,MEMF_CHIP)) == NULL)
  113.                     {
  114.                         FreeMem(tempbm,sizeof(*tempbm));
  115.                         FreeMem(temprp,sizeof(*temprp));
  116.                         temprp = NULL;
  117.                     }
  118.                     else
  119.                     {
  120.                         int i;
  121.  
  122.                         /* initialize plane pointers for temp bitmap */
  123.  
  124.                         for(i=0; i<tempbm->Depth; i++)
  125.                         {
  126.                             tempbm->Planes[i] = mem+(tempbm->BytesPerRow * i);
  127.                         }
  128.  
  129.                         /* link tempbm to temprp */
  130.  
  131.                         temprp->BitMap = tempbm;
  132.  
  133.                         /* exit */
  134.                     }
  135.                 }
  136.             }
  137.         }
  138.     }
  139.     return(temprp);
  140. }
  141.  
  142. scale_rastport(srcrp,srcr,dstrp,dstr)
  143. struct RastPort  *srcrp;
  144. struct Rectangle *srcr;
  145. struct RastPort  *dstrp;
  146. struct Rectangle *dstr;
  147. {
  148.     LONG error = FALSE;
  149.  
  150.     /* origin of source rectangle */
  151.  
  152.     WORD x = srcr->MinX;
  153.     WORD y = srcr->MinY;
  154.     WORD X = dstr->MinX;
  155.     WORD Y = dstr->MinY;
  156.  
  157.     /* scale from m x n src rectangle to M x N dst rectangle */
  158.  
  159.     WORD m = (srcr->MaxX - x) + 1;
  160.     WORD n = (srcr->MaxY - y) + 1;
  161.     WORD M = (dstr->MaxX - X) + 1;
  162.     WORD N = (dstr->MaxY - Y) + 1;
  163.  
  164.     /* map pixels from source to destination bitmap */
  165.  
  166.     LONG I = 0;
  167.     LONG J = 0;
  168.  
  169.     LONG II = 0;
  170.     LONG JJ = 0;
  171.  
  172.     /* readpixelarray */
  173.  
  174.     struct RastPort *temprp = get_temprp(srcrp);
  175.  
  176.     if(temprp)
  177.     {
  178.         UWORD *array = (UWORD *) AllocMem((m*2),MEMF_PUBLIC|MEMF_CLEAR);
  179.         WORD n_err_N = 0; 
  180.  
  181.         if(array) 
  182.         {
  183.             WORD rectflag = FALSE;
  184.             WORD M_div_m = 0;
  185.             WORD N_div_n = 0;
  186.             WORD m_mod_M;
  187.             WORD n_mod_N;
  188.             WORD m_neg_M;
  189.             WORD n_neg_N;
  190.             LONG iii;
  191.             LONG jjj;
  192.             LONG ii;
  193.             LONG jj;
  194.  
  195.             /* initialize static variables */
  196.  
  197.             /* M_div_m = M/m; */
  198.             /* N_div_n = N/n; */
  199.  
  200.             m_mod_M = m%M;
  201.             n_mod_N = n%N;
  202.  
  203.             /* increments to write by */
  204.  
  205.             iii = (M_div_m < 1) ? 1: M_div_m;
  206.             jjj = (N_div_n < 1) ? 1: N_div_n;
  207.  
  208.             /* write pixels or rectangles? */
  209.  
  210.             if((iii>1)||(jjj>1)) rectflag = TRUE;
  211.  
  212.             /* scaling variables */
  213.  
  214.             m_neg_M = (m_mod_M-m) * iii;
  215.  
  216.             n_neg_N = (n_mod_N-n) * jjj;
  217.  
  218.             /* for all pixels in the destination rectangle */
  219.  
  220.             kprintf("scale_rastport: M == %ld, N == %ld\n",M,N);
  221.  
  222.             for(J=0; J<N; J+=jjj)
  223.             { 
  224.                 WORD m_err_M = 0; 
  225.  
  226.                 /* map line to destination */
  227.  
  228.                 II = 0;
  229.  
  230.                 jj = JJ/N;
  231.  
  232.                 /* determine first most popular j */
  233.                 {
  234.                     WORD n_ERR_N = (n_err_N)%N; 
  235.                     LONG j = jj;
  236.                     WORD n_last_N = -n_ERR_N;
  237.                     WORD n_next_N = N;
  238.  
  239.                     n_ERR_N += n; 
  240.  
  241.                     /* until next dest pixel */
  242.  
  243.                     n_ERR_N -= N; 
  244.  
  245.                     while(!(n_ERR_N < 0))
  246.                     {
  247.                         if(n_next_N > n_last_N)
  248.                         {
  249.                             n_last_N = n_next_N;
  250.                             j++;
  251.                         }
  252.                         n_ERR_N -= N; 
  253.                     }
  254.                     n_next_N += n_ERR_N;
  255.  
  256.                     if(n_next_N > n_last_N)
  257.                     {
  258.                         n_last_N = n_next_N;
  259.                         j++;
  260.                     }
  261.  
  262.                     ReadPixelLine(srcrp,x,y+j,m,array,NULL,temprp);
  263.                 }
  264.  
  265.  
  266.                 for(I=0; I<M; I+=iii)
  267.                 {
  268.  
  269.                     ii = II/M;
  270.  
  271.                     /* map pixel to destination */
  272.                     {
  273.                         /* determine first most popular i */
  274.  
  275.                         WORD m_ERR_M = (m_err_M)%M;
  276.                         LONG i = ii;
  277.                         WORD m_last_M = -m_ERR_M;
  278.                         WORD m_next_M = M;
  279.  
  280.                         m_ERR_M += m; 
  281.  
  282.                         /* until next dest pixel */
  283.  
  284.                         m_ERR_M -= M; 
  285.  
  286.                         while(!(m_ERR_M < 0))
  287.                         {
  288.                             if(m_next_M > m_last_M)
  289.                             {
  290.                                 m_last_M = m_next_M;
  291.                                 i++;
  292.                             }
  293.                             m_ERR_M -= M; 
  294.                         }
  295.                         m_next_M += m_ERR_M;
  296.  
  297.                         if(m_next_M > m_last_M)
  298.                         {
  299.                             m_last_M = m_next_M;
  300.                             i++;
  301.                         }
  302.  
  303.                         /* map pixel */
  304.  
  305.                         SetAPen(dstrp,*(array+i));
  306.  
  307.                         if(rectflag)
  308.                         {
  309.                             RectFill(dstrp,X+I,Y+J,X+I+iii-1,Y+J+jjj-1);
  310.                         }
  311.                         else
  312.                         {
  313.                             WritePixel(dstrp,X+I,Y+J);
  314.                         }
  315.  
  316.                     }
  317.  
  318.                     m_err_M += m_neg_M;
  319.  
  320.                     II += m * iii;
  321.  
  322.                     if(error) break;
  323.                 }
  324.  
  325.                 n_err_N += n_neg_N;
  326.  
  327.                 JJ += n * jjj;
  328.  
  329.                 if(error) break;
  330.             }
  331.  
  332.             FreeMem(array,(m*2));
  333.         }
  334.         else
  335.         {
  336.             error = TRUE;
  337.         }
  338.  
  339.         dispose_temprp(temprp);
  340.     }
  341.     else
  342.     {
  343.         error = TRUE;
  344.     }
  345.  
  346.     return(error);
  347. }
  348.